package cn.maihe.elg.operation.service.system.impl;

import cn.maihe.elg.operation.exception.ErrorCode;
import cn.maihe.elg.operation.exception.SystemRuntimeException;
import cn.maihe.elg.operation.model.enums.DelFlagEnum;
import cn.maihe.elg.operation.model.enums.RoleType;
import cn.maihe.elg.operation.model.enums.UserStatusEnum;
import cn.maihe.elg.operation.model.vo.Query;
import cn.maihe.elg.operation.repository.entity.OrganizationDO;
import cn.maihe.elg.operation.repository.entity.OrganizationDOCondition;
import cn.maihe.elg.operation.repository.entity.UserDO;
import cn.maihe.elg.operation.repository.mapper.OrganizationMapper;
import cn.maihe.elg.operation.repository.mapper.UserMapper;
import cn.maihe.elg.operation.service.BaseDaoService;
import cn.maihe.elg.operation.service.system.OrganizationService;
import cn.maihe.elg.operation.service.system.UserService;
import cn.maihe.elg.operation.utils.DateUtil;
import cn.maihe.elg.operation.utils.IdGenerate;
import cn.maihe.elg.operation.utils.OrgCodeHandler;
import cn.maihe.framework.starter.mybatis.dao.MybatisDaoImpl;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * @author JHWei on 2018-07-13.
 * @ 创建日期：2018-07-13
 */
@Service
@Slf4j
public class OrganizationServiceImpl extends BaseDaoService<OrganizationDO> implements OrganizationService {

    @Resource
    private OrganizationMapper organizationMapper;
    @Resource
    private UserMapper userMapper;

    @Resource
    private UserService userService;

    @Resource
    private OrgCodeHandler orgCodeHandler;


    /**
     * 新增机构
     *
     * @param organization 机构信息
     * @param user
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void createOrganization(OrganizationDO organization, UserDO user) {

        // 判断登录账号和状态判断是否重复
        Integer countUserName = userMapper.selectCount(new EntityWrapper<UserDO>()
                .eq("username", user.getUsername())
                .ne("status", UserStatusEnum.DELETED.toString()));
        if (countUserName > 0) {
            log.error("创建用户失败， 登录账号重复");
            throw new SystemRuntimeException(ErrorCode.BSMUM001, user.getUsername());
        }
        // 判断姓名和状态判断是否重复
        Integer countName = userMapper.selectCount(new EntityWrapper<UserDO>()
                .eq("name", user.getName())
                .ne("status", UserStatusEnum.DELETED.toString()));
        if (countName > 0) {
            log.error("创建用户失败， 姓名重复");
            throw new SystemRuntimeException(ErrorCode.BSMUM001, user.getName());
        }

        String orgCode = organization.getOrgCode();
        if (organization.getParentId() == null) {
            organization.setParentId(0L);
        }
        //机构名称不允许重复。
        Integer nameOrg = organizationMapper.selectCount(new EntityWrapper<OrganizationDO>()
                .eq("full_name", organization.getFullName()));
        if (nameOrg > 0) {
            throw new SystemRuntimeException(ErrorCode.BSMOM004);
        }
        //机构代码不允许重复。
        Integer codeOrg = organizationMapper.selectCount(new EntityWrapper<OrganizationDO>()
                .eq("org_code", organization.getOrgCode()));
        if (codeOrg > 0) {
            throw new SystemRuntimeException(ErrorCode.BSMOM004);
        }

        user.setPassword(new BCryptPasswordEncoder().encode(user.getPassword()));
        user.setPwdExpiredTime(DateUtil.getDayAfter(90));
        user.setGmtCreate(new Date());
        user.setGmtModified(new Date());
        user.setUserCreate(userService.getUserContext().getUsername());
        user.setUserModified(userService.getUserContext().getUsername());
        organization.setGmtCreate(new Date());
        organization.setUserCreate(userService.getUserContext().getUsername());
        organization.setGmtModified(new Date());
        organization.setUserModified(userService.getUserContext().getUsername());
        OrganizationDO org = organizationMapper.selectOne(OrganizationDO.builder().fullName(organization.getFullName()).build());
        if (org != null) {
            throw new SystemRuntimeException(ErrorCode.BSMOM004);
        }
        Integer resInt = organizationMapper.selectCount(new EntityWrapper<OrganizationDO>()
                .eq("org_code", orgCode));
        if (resInt == 0) {
//            organization.setId(Constants.ORG_ID);
            user.setId(IdGenerate.getId());
            user.setOrgId(organization.getId());
            organization.setUserId(user.getId());
            organizationMapper.insert(organization);
            userMapper.insert(user);
            //TODO 用户权限
            userMapper.insertUserRole(RoleType.ORG.getType(), user.getId());
        } else {
            throw new SystemRuntimeException(ErrorCode.BSMOM004);
        }
    }


    /**
     * 查询机构列表
     * //     * @param name 机构名称(模糊查询)
     * //     * @param  机构代码
     * //     * @param  当前页码
     * //     * @param  页面大小
     *
     * @return 分页机构数据
     */

    @Override
    public PageInfo<OrganizationDO> findOrganizationByPage(Query obj) {
        try {
            obj.setPageNo(obj.getPageNo() == 0 ? 1 : obj.getPageNo());
            obj.setPageSize(obj.getPageSize() == 0 ? 10 : obj.getPageSize());
            PageHelper.startPage(obj.getPageNo(), obj.getPageSize());
            PageHelper.orderBy("gmt_modified desc");
            Map map = orgCodeHandler.getCode(obj.getParameters());
//            MybatisDaoImpl.of(OrganizationMapper.class).selectListBySql("findByNameLikeAndOrgCodeAndDelFlag", map);
            List<OrganizationDO> page = organizationMapper.findByNameLikeAndOrgCodeAndDelFlag(map);
            return new PageInfo<>(page);
        } catch (Exception e) {
            throw new SystemRuntimeException(ErrorCode.BSMSC009);
        }

    }

    /**
     * 获取机构详情信息
     *
     * @param id 机构ID
     * @return id 对应机构
     */
    @Override
    public OrganizationDO getOrganization(Long id) {
        return organizationMapper.selectById(id);
    }

    /**
     * 获取租户机构代码
     *
     * @param id 机构ID
     * @return id 对应机构
     */
    @Override
    public String getOrganizationCode(Long id) {
        OrganizationDO organizationDO = organizationMapper.selectById(id);
        return organizationDO.getOrgCode();
    }

    /**
     * 修改机构信息
     *
     * @param organization 机构信息
     */
    @Override
    @Transactional
    public void modifyOrganization(OrganizationDO organization) {
        Long id = organization.getId();
        if (id == null) {
            log.error("机构不存在或已被删除");
            throw new SystemRuntimeException(ErrorCode.BSMOM003);
        }
        OrganizationDO tempOrg = organizationMapper.selectById(id);
        if (tempOrg == null) {
            log.error("机构不存在或已被删除");
            throw new SystemRuntimeException(ErrorCode.BSMOM003);
        }
        String orgCode = organization.getOrgCode();
        String fullName = organization.getFullName();
        //机构名称不允许重复。
        Integer nameOrg = organizationMapper.selectCount(new EntityWrapper<OrganizationDO>()
                .eq("full_name", fullName)
                .ne("id", organization.getId()));
        if (nameOrg > 0) {
            throw new SystemRuntimeException(ErrorCode.BSMOM004);
        }
        //机构代码不允许重复。
        Integer codeOrg = organizationMapper.selectCount(new EntityWrapper<OrganizationDO>()
                .eq("org_code", orgCode)
                .ne("id", organization.getId()));
        if (codeOrg > 0) {
            throw new SystemRuntimeException(ErrorCode.BSMOM004);
        }

        if (organization.getParentId() == null) {
            organization.setParentId(0L);
        }
        try {
            organization.setGmtModified(new Date());
            organization.setUserModified(userService.getUserContext().getUsername());
            // 目前机构代码是可以修改       organization.setOrgCode(null);//机构代码不修改
            organizationMapper.updateById(organization);
        } catch (Exception e) {
            throw new SystemRuntimeException(ErrorCode.BSMSC007);
        }
    }


    /**
     * 删除机构
     * 被代付客户关联的机构无法删除
     *
     * @param id 机构ID
     */
    @Override
    public void deleteOrganization(Long id) {
        OrganizationDO organization = organizationMapper.selectById(id);
        if (organization == null) {
            throw new SystemRuntimeException(ErrorCode.BSMCM001);
        }
        //TODO 存在关联用户不能删除
        Integer resCount = 0;
        if (resCount > 0) {
            throw new SystemRuntimeException(ErrorCode.BSMOM005);
        }
        organizationMapper.deleteById(id);
    }

    @Override
    public OrganizationDO getOrganizationByCode(String orgCode) {
        if (StringUtils.isBlank(orgCode) || "-1".equals(orgCode)) {
            return null;
        }
        OrganizationDO organizationDO = MybatisDaoImpl.run().selectOne(OrganizationDOCondition.builder().andOrgCodeEq(orgCode).andDelFlagEq(DelFlagEnum.NORMAL.getValue()).build());
        if (organizationDO == null) {
            throw new SystemRuntimeException(ErrorCode.BSMCM001);
        }
        return organizationDO;
    }

    @Override
    public Integer getAuditTotal() {
        return organizationMapper.selectCount(OrganizationDOCondition.builder().andAuditStatusEq(2).build());
    }

}
